#include "MixAlgorithm.h"
#include <stdint.h>

namespace MixAlgorithm
{
	
	void straight16(uint8_t* buffA, int lenA, uint8_t* buffB, int lenB,
		float proportionA, float proportionB) {
		int16_t* tempA = (int16_t*)buffA;
		int16_t* tempB = (int16_t*)buffB;
		for (int i = 0;i < lenA/2 && i < lenB/2; ++i)
		{
			*tempA *= proportionA;
			*tempA += *tempB * proportionB;
			++tempA;
			++tempB;
		}
	}


	void straight16_smooth(uint8_t* buffA, int lenA, uint8_t* buffB, int lenB,
		float proportionA, float proportionB,
		uint8_t* old_buffA, int old_lenA, uint8_t* old_buffB, int old_lenB,
		float old_proportionA, float old_proportionB) {

		int minSize = lenA / 2;
		if (minSize > lenB / 2) minSize = lenB / 2;
		if (minSize > old_lenA / 2) minSize = old_lenA / 2;
		if (minSize > old_lenB / 2) minSize = old_lenB / 2;

		int16_t* tempA = (int16_t*)buffA;
		int16_t* tempB = (int16_t*)buffB;

		int16_t* old_tempA = (int16_t*)old_buffA;
		int16_t* old_tempB = (int16_t*)old_buffB;


		int smooth = minSize;
		int16_t old_V = 0;

		for (int i = 0; i < minSize; ++i){
			if (i < smooth){
                
				float p = (float)i / (float)smooth;
				old_V = *old_tempA * old_proportionA;
				old_V += *old_tempB * old_proportionB;
                
				++old_tempA;
				++old_tempB;
				*tempA *= proportionA;
				*tempA += *tempB * proportionB;

				*tempA *= p;
				*tempA += old_V * (1 - p);

				++tempA;
				++tempB;
			}
			else {
				*tempA *= proportionA;
				*tempA += *tempB * proportionB;
				++tempA;
				++tempB;
			}

		}
	}
    
    
    
    int audio16_mix(uint8_t* buffA,float proportionA,
                    uint8_t* buffB,float proportionB,
                    uint8_t* old_buffA,float old_proportionA,
                    uint8_t* old_buffB,float old_proportionB,
                    float startProportion,float changeProportion,
                    uint8_t* destBuff,uint32_t len){
        
        
        int16_t* tempA = (int16_t*)buffA;
        int16_t* tempB = (int16_t*)buffB;
        
        int16_t* old_tempA = (int16_t*)old_buffA;
        int16_t* old_tempB = (int16_t*)old_buffB;
        
        
        int16_t* destTemp = (int16_t*)destBuff;
        
        float newProportion = startProportion;
        
        int minSize = len / 2;

        int16_t old_V = 0;
        
        for (int i = 0; i < minSize; ++i){
            if (newProportion < 1.0f){
                
//                if (buffA == old_buffA && buffB == old_buffB) {
//                    *destTemp = *tempA * proportionA;
//                    *destTemp += *tempB * proportionB;
//                }else
                {
                    //float p = (float)i / (float)smooth;
                    old_V = *old_tempA * old_proportionA;
                    old_V += *old_tempB * old_proportionB;
                    
                    *destTemp = *tempA * proportionA;
                    *destTemp += *tempB * proportionB;
                    
                    *destTemp *= newProportion;
                    *destTemp += old_V * (1 - newProportion);
                }


            } else {
                *destTemp = *tempA * proportionA;
                *destTemp += *tempB * proportionB;

            }
            ++old_tempA;
            ++old_tempB;
            ++tempA;
            ++tempB;
            ++destTemp;
            newProportion += changeProportion;
        }
        return len;
    }
};
